import $ from 'jquery';
let util = {
    getNetworkType: function() {//移动判断网络类型
        var ua = navigator.userAgent;
        var networkStr = ua.match(/NetType\/\w+/) ? ua.match(/NetType\/\w+/)[0] : 'NetType/other';
        networkStr = networkStr.toLowerCase().replace('nettype/', '');
        var networkType;
        switch(networkStr) {
            case 'wifi':
                networkType = 'wifi';
                break;
            case '5g':
                networkType = '5g';
                break;
            case 'non_network':
                networkType = '5g';
                break;
            case '4g':
                networkType = '4g';
                break;
            case '3g':
                networkType = '3g';
                break;
            case '3gnet':
                networkType = '3g';
                break;
            case '2g':
                networkType = '2g';
                break;
            default:
                networkType = 'other';
        }
        return networkType;//wift/5g/4g/3g/2g/other
    },
    supportsNativeHls: function(){//移动设备对m3u8原生解析是否支持
        var a = document.createElement("video");
        var b = ["application/vnd.apple.mpegurl", "audio/mpegurl", "audio/x-mpegurl", "application/x-mpegurl", "video/x-mpegurl", "video/mpegurl", "application/mpegurl"];
        return b.some(function(b) {
            return /maybe|probably/i.test(a.canPlayType(b))
        });
    },
    supportsMSE: function(){
        var mediaSource = window.MediaSource || window.WebKitMediaSource;
        var sourceBuffer = window.SourceBuffer || window.WebKitSourceBuffer;
        var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');

        // if SourceBuffer is exposed ensure its API is valid
        // safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
        var sourceBufferValidAPI = !sourceBuffer || (sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === 'function' && typeof sourceBuffer.prototype.remove === 'function');
        return !!isTypeSupported && !!sourceBufferValidAPI;
    },
    supportMSEH264Playback: function() {
        var mediaSource = window.MediaSource || window.WebKitMediaSource;
        var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');
        return isTypeSupported;
    },
    supportNativeMediaPlayback: function(mimeType){
        var ele = window.document.createElement('video');
        var canPlay = ele.canPlayType(mimeType);
        return canPlay === 'probably' || canPlay == 'maybe';
    },
    $fn: (function(){
        
        if($ && "fn" in $ && $.fn.toString() == "[object Object]"){
            //封装基于jQuery的同时兼容单击、移动事件
            $.fn.tclick = function(starthandler, movehandler, moveendhandler, endhandler){
                var _self = this;
                _self.on("touchstart.xtplayer", function(e){
                    e = e.originalEvent;
                    var isMove = false;
                    var touch = e.touches[0]; // touches数组对象获得屏幕上所有的touch，取第一个touch
                    var startPos = { // 取第一个touch的坐标值
                        x: touch.pageX,
                        y: touch.pageY,
                        time: new Date().getTime()
                    };
                    var endPos = null;
                    if(starthandler && typeof starthandler == "function"){
                        starthandler(e, startPos);
                    }
                    
                    function touchMove(e1){
                        e1 = e1.originalEvent;
                        if (e1.touches.length > 1 || e1.scale && e1.scale !== 1) return;
                        var touch1 = e1.touches[0];
                        endPos = {
                            x: touch1.pageX,
                            y: touch1.pageY
                        };
//            				var distance = Math.sqrt(Math.pow(endPos.x-startPos.x, 2) + Math.pow(endPos.y -startPos.y, 2));
//            				if(distance > 10){
//            					isMove = true;
//            				}
                        isMove = true;
                        if(movehandler && typeof movehandler == "function"){
                            movehandler(e1, endPos);
                        }
                    }
                    function touchEnd(e2){
                        e2 = e2.originalEvent;
                        if(isMove && moveendhandler && typeof moveendhandler == "function"){
                            moveendhandler(e2, endPos);
                        }else{
                            if(endhandler && typeof endhandler == "function"){
                                endhandler(e2,startPos);
                            }
                        }
                        
                        _self.off("touchmove.xtplayer", touchMove);
                        _self.off("touchend.xtplayer", touchEnd);
                    }
                    _self.off("touchmove.xtplayer", touchMove);
                    _self.off("touchend.xtplayer", touchEnd);
                    _self.on("touchmove.xtplayer", touchMove);
                    _self.on("touchend.xtplayer", touchEnd);
                });//touchstart---end
            };
        }
        
    })(),
    fullScreenApi: function() {
        /*
        * jquery.fullscreen v0.5.1
        * https://github.com/private-face/jquery.fullscreen
        *
        * Copyright (c) 2012–2015 Vladimir Zhuravlev
        * Released under the MIT license
        * https://github.com/private-face/jquery.fullscreen/blob/master/LICENSE
        *
        * Date: 2015-06-15
        **/
        (function(global, factory) {
            // CommonJS/Browserify
            if (false) {
                factory(require('jquery'));
                // Global
            } else {
                
            }
        }(this, function($) {
            function defined(a) {
                return typeof a !== "undefined";
            }

            function extend(child, parent, prototype) {
                var F = function() {};
                F.prototype = parent.prototype;
                child.prototype = new F();
                child.prototype.constructor = child;
                parent.prototype.constructor = parent;
                child._super = parent.prototype;
                if (prototype) {
                    $.extend(child.prototype, prototype);
                }
            }

            var SUBST = [
                ["", ""],
                ["exit", "cancel"],
                ["screen", "Screen"]
            ];

            var VENDOR_PREFIXES = ["", "o", "ms", "moz", "webkit", "webkitCurrent"];

            function native(obj, name) {
                var prefixed;
                if (typeof obj === "string") {
                    name = obj;
                    obj = document;
                }
                for (var i = 0; i < SUBST.length; ++i) {
                    name = name.replace(SUBST[i][0], SUBST[i][1]);
                    for (var j = 0; j < VENDOR_PREFIXES.length; ++j) {
                        prefixed = VENDOR_PREFIXES[j];
                        prefixed += j === 0 ? name : name.charAt(0).toUpperCase() + name.substr(1);
                        if (defined(obj[prefixed])) {
                            return obj[prefixed];
                        }
                    }
                }
                return void 0;
            }

            var ua = navigator.userAgent;

            var fsEnabled = native("fullscreenEnabled");

            var parsedChromeUA = ua.match(/Android.*Chrome\/(\d+)\./);

            var IS_ANDROID_CHROME = !!parsedChromeUA;

            var CHROME_VERSION, ANDROID_CHROME_VERSION;

            if (IS_ANDROID_CHROME) {
                ANDROID_CHROME_VERSION = parseInt(parsedChromeUA[1]);
            }

            var IS_NATIVELY_SUPPORTED = (!IS_ANDROID_CHROME || ANDROID_CHROME_VERSION > 37) && defined(native("fullscreenElement")) && (!defined(fsEnabled) || fsEnabled === true);

            var version = $.fn.jquery.split(".");

            var JQ_LT_17 = parseInt(version[0]) < 2 && parseInt(version[1]) < 7;

            var FullScreenAbstract = function() {
                this.__options = null;
                this._fullScreenElement = null;
                this.__savedStyles = {};
            };

            FullScreenAbstract.prototype = {
                "native": native,
                _DEFAULT_OPTIONS: {
                    styles: {
                        boxSizing: "border-box",
                        MozBoxSizing: "border-box",
                        WebkitBoxSizing: "border-box"
                    },
                    toggleClass: null
                },
                __documentOverflow: "",
                __htmlOverflow: "",
                _preventDocumentScroll: function() {
                    this.__documentOverflow = document.body.style.overflow;
                    this.__htmlOverflow = document.documentElement.style.overflow;
                    if (!$(this._fullScreenElement).is("body, html")) {
                        $("body, html").css("overflow", "hidden");
                    }
                },
                _allowDocumentScroll: function() {
                    document.body.style.overflow = this.__documentOverflow;
                    document.documentElement.style.overflow = this.__htmlOverflow;
                },
                _fullScreenChange: function() {
                    if (!this.__options) {
                        return;
                    }
                    if (!this.isFullScreen()) {
                        this._allowDocumentScroll();
                        this._revertStyles();
                        this._triggerEvents();
                        this._fullScreenElement = null;
                    } else {
                        this._preventDocumentScroll();
                        this._triggerEvents();
                    }
                },
                _fullScreenError: function(e) {
                    if (!this.__options) {
                        return;
                    }
                    this._revertStyles();
                    this._fullScreenElement = null;
                    if (e) {
                        $(document).trigger("fscreenerror", [e]);
                    }
                },
                _triggerEvents: function() {
                    $(this._fullScreenElement).trigger(this.isFullScreen() ? "fscreenopen" : "fscreenclose");
                    $(document).trigger("fscreenchange", [this.isFullScreen(), this._fullScreenElement]);
                },
                _saveAndApplyStyles: function() {
                    var $elem = $(this._fullScreenElement);
                    this.__savedStyles = {};
                    for (var property in this.__options.styles) {
                        this.__savedStyles[property] = this._fullScreenElement.style[property];
                        this._fullScreenElement.style[property] = this.__options.styles[property];
                    }
                    if ($elem.is("body")) {
                        document.documentElement.style.overflow = this.__options.styles.overflow;
                    }
                    if (this.__options.toggleClass) {
                        $elem.addClass(this.__options.toggleClass);
                    }
                },
                _revertStyles: function() {
                    var $elem = $(this._fullScreenElement);
                    for (var property in this.__options.styles) {
                        this._fullScreenElement.style[property] = this.__savedStyles[property];
                    }
                    if ($elem.is("body")) {
                        document.documentElement.style.overflow = this.__savedStyles.overflow;
                    }
                    if (this.__options.toggleClass) {
                        $elem.removeClass(this.__options.toggleClass);
                    }
                },
                open: function(elem, options) {
                    if (elem === this._fullScreenElement) {
                        return;
                    }
                    if (this.isFullScreen()) {
                        this.exit();
                    }
                    this._fullScreenElement = elem;
                    this.__options = $.extend(true, {}, this._DEFAULT_OPTIONS, options);
                    this._saveAndApplyStyles();
                },
                exit: null,
                isFullScreen: null,
                isNativelySupported: function() {
                    return IS_NATIVELY_SUPPORTED;
                }
            };

            var FullScreenNative = function() {
                FullScreenNative._super.constructor.apply(this, arguments);
                this.exit = $.proxy(native("exitFullscreen"), document);
                this._DEFAULT_OPTIONS = $.extend(true, {}, this._DEFAULT_OPTIONS, {
                    styles: {
                        width: "100%",
                        height: "100%"
                    }
                });
                $(document).bind(this._prefixedString("fullscreenchange") + " MSFullscreenChange", $.proxy(this._fullScreenChange, this)).bind(this._prefixedString("fullscreenerror") + " MSFullscreenError", $.proxy(this._fullScreenError, this));
            };

            extend(FullScreenNative, FullScreenAbstract, {
                VENDOR_PREFIXES: ["", "o", "moz", "webkit"],
                _prefixedString: function(str) {
                    return $.map(this.VENDOR_PREFIXES, function(s) {
                        return s + str;
                    }).join(" ");
                },
                open: function(elem, options) {
                    FullScreenNative._super.open.apply(this, arguments);
                    var requestFS = native(elem, "requestFullscreen");
                    requestFS.call(elem);
                },
                exit: $.noop,
                isFullScreen: function() {
                    return native("fullscreenElement") !== null;
                },
                element: function() {
                    return native("fullscreenElement");
                }
            });

            var FullScreenFallback = function() {
                FullScreenFallback._super.constructor.apply(this, arguments);
                this._DEFAULT_OPTIONS = $.extend({}, this._DEFAULT_OPTIONS, {
                    styles: {
                        position: "fixed",
                        zIndex: "2147483647",
                        left: 0,
                        top: 0,
                        bottom: 0,
                        right: 0
                    }
                });
                this.__delegateKeydownHandler();
            };

            extend(FullScreenFallback, FullScreenAbstract, {
                __isFullScreen: false,
                __delegateKeydownHandler: function() {
                    var $doc = $(document);
                    $doc.delegate("*", "keydown.fullscreen", $.proxy(this.__keydownHandler, this));
                    var data = JQ_LT_17 ? $doc.data("events") : $._data(document).events;
                    var events = data["keydown"];
                    if (!JQ_LT_17) {
                        events.splice(0, 0, events.splice(events.delegateCount - 1, 1)[0]);
                    } else {
                        data.live.unshift(data.live.pop());
                    }
                },
                __keydownHandler: function(e) {
                    if (this.isFullScreen() && e.which === 27) {
                        this.exit();
                        return false;
                    }
                    return true;
                },
                _revertStyles: function() {
                    FullScreenFallback._super._revertStyles.apply(this, arguments);
                    this._fullScreenElement.offsetHeight;
                },
                open: function(elem) {
                    FullScreenFallback._super.open.apply(this, arguments);
                    this.__isFullScreen = true;
                    this._fullScreenChange();
                },
                exit: function() {
                    if (!this.__isFullScreen) {
                        return;
                    }
                    this.__isFullScreen = false;
                    this._fullScreenChange();
                },
                isFullScreen: function() {
                    return this.__isFullScreen;
                },
                element: function() {
                    return this.__isFullScreen ? this._fullScreenElement : null;
                }
            });

            $.fullscreen = IS_NATIVELY_SUPPORTED ? new FullScreenNative() : new FullScreenFallback();

            $.fn.fullscreen = function(options) {
                var elem = this[0];
                options = $.extend({
                    toggleClass: null,
                    overflow: "hidden"
                }, options);
                options.styles = {
                    overflow: options.overflow
                };
                delete options.overflow;
                if (elem) {
                    $.fullscreen.open(elem, options);
                    typeof options.xmcalback == 'function' && options.xmcalback();
                }
                return this;
            };
            return $.fullscreen;
        }));
    },
    timeFull: function(time) {
        var hours, minutes, seconds;

        var _pad = function(number) {
            if (number < 10) {
                return '0' + number;
            } else {
                return '' + number;
            }
        };

        if (time < 0) {
            time = 0;
        }

        seconds = Math.floor(time);
        minutes = Math.floor(seconds / 60);
        hours = Math.floor(minutes / 60);
        seconds = seconds % 60;
        minutes = minutes % 60;
        return '' + _pad(hours) + ':' + _pad(minutes) + ':' + _pad(seconds % 60);
    },
    addZero: function(num) {
        if (num < 10) {
            num = ('0' + num.toString());
        }
        return num;
    },
    dprAndScale: function(){
        var doc = window.document;
        var docEl = doc.documentElement;
        var metaEl = doc.querySelector('meta[name="viewport"]');
        var flexibleEl = doc.querySelector('meta[name="flexible"]');
        var dpr = 0;
        var scale = 0;
        if (metaEl) {
            //console.warn('将根据已有的meta标签来设置缩放比例');
            var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
            if (match) {
                scale = parseFloat(match[1]);
                dpr = parseInt(1 / scale);
            }
        } else if (flexibleEl) {
            var content = flexibleEl.getAttribute('content');
            if (content) {
                var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
                var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
                if (initialDpr) {
                    dpr = parseFloat(initialDpr[1]);
                    scale = parseFloat((1 / dpr).toFixed(2));    
                }
                if (maximumDpr) {
                    dpr = parseFloat(maximumDpr[1]);
                    scale = parseFloat((1 / dpr).toFixed(2));    
                }
            }
        }
        if (!dpr && !scale) {
            var isAndroid = window.navigator.appVersion.match(/android/gi);
            var isIPhone = window.navigator.appVersion.match(/iphone/gi);
            var devicePixelRatio = window.devicePixelRatio;
            if (isIPhone) {
                // iOS下，对于2和3的屏，用2倍的方案，其余的用1倍方案
                if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
                    dpr = 3;
                } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                    dpr = 2;
                } else {
                    dpr = 1;
                }
            } else {
                // 其他设备下，仍旧使用1倍的方案
                dpr = 1;
            }
            scale = 1 / dpr;
        }
        return {
            dpr: dpr,
            scale: scale
        }
    },
    uuid: function(){
        return 'xxxxxyxxxxxyxx4xxxyxxxxxyxxxxxyxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        });
    },
    md5: function() {
        /*
        * JavaScript MD5 1.0.1
        * https://github.com/blueimp/JavaScript-MD5
        *
        * Copyright 2011, Sebastian Tschan
        * https://blueimp.net
        *
        * Licensed under the MIT license:
        * http://www.opensource.org/licenses/MIT
        *
        * Based on
        * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
        * Digest Algorithm, as defined in RFC 1321.
        * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
        * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
        * Distributed under the BSD License
        * See http://pajhome.org.uk/crypt/md5 for more info.
        */

        /*jslint bitwise: true */
        /*global unescape, define */

        (function($) {
            'use strict';

            /*
            * Add integers, wrapping at 2^32. This uses 16-bit operations internally
            * to work around bugs in some JS interpreters.
            */
            function safe_add(x, y) {
                var lsw = (x & 0xFFFF) + (y & 0xFFFF),
                    msw = (x >> 16) + (y >> 16) + (lsw >> 16);
                return (msw << 16) | (lsw & 0xFFFF);
            }

            /*
            * Bitwise rotate a 32-bit number to the left.
            */
            function bit_rol(num, cnt) {
                return (num << cnt) | (num >>> (32 - cnt));
            }

            /*
            * These functions implement the four basic operations the algorithm uses.
            */
            function md5_cmn(q, a, b, x, s, t) {
                return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
            }

            function md5_ff(a, b, c, d, x, s, t) {
                return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
            }

            function md5_gg(a, b, c, d, x, s, t) {
                return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
            }

            function md5_hh(a, b, c, d, x, s, t) {
                return md5_cmn(b ^ c ^ d, a, b, x, s, t);
            }

            function md5_ii(a, b, c, d, x, s, t) {
                return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
            }

            /*
            * Calculate the MD5 of an array of little-endian words, and a bit length.
            */
            function binl_md5(x, len) {
                /* append padding */
                x[len >> 5] |= 0x80 << (len % 32);
                x[(((len + 64) >>> 9) << 4) + 14] = len;

                var i, olda, oldb, oldc, oldd,
                    a = 1732584193,
                    b = -271733879,
                    c = -1732584194,
                    d = 271733878;

                for (i = 0; i < x.length; i += 16) {
                    olda = a;
                    oldb = b;
                    oldc = c;
                    oldd = d;

                    a = md5_ff(a, b, c, d, x[i], 7, -680876936);
                    d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
                    c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
                    b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
                    a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
                    d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
                    c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
                    b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
                    a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
                    d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
                    c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
                    b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
                    a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
                    d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
                    c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
                    b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);

                    a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
                    d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
                    c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
                    b = md5_gg(b, c, d, a, x[i], 20, -373897302);
                    a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
                    d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
                    c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
                    b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
                    a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
                    d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
                    c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
                    b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
                    a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
                    d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
                    c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
                    b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);

                    a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
                    d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
                    c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
                    b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
                    a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
                    d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
                    c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
                    b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
                    a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
                    d = md5_hh(d, a, b, c, x[i], 11, -358537222);
                    c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
                    b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
                    a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
                    d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
                    c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
                    b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);

                    a = md5_ii(a, b, c, d, x[i], 6, -198630844);
                    d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
                    c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
                    b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
                    a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
                    d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
                    c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
                    b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
                    a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
                    d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
                    c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
                    b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
                    a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
                    d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
                    c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
                    b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);

                    a = safe_add(a, olda);
                    b = safe_add(b, oldb);
                    c = safe_add(c, oldc);
                    d = safe_add(d, oldd);
                }
                return [a, b, c, d];
            }

            /*
            * Convert an array of little-endian words to a string
            */
            function binl2rstr(input) {
                var i,
                    output = '';
                for (i = 0; i < input.length * 32; i += 8) {
                    output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
                }
                return output;
            }

            /*
            * Convert a raw string to an array of little-endian words
            * Characters >255 have their high-byte silently ignored.
            */
            function rstr2binl(input) {
                var i,
                    output = [];
                output[(input.length >> 2) - 1] = undefined;
                for (i = 0; i < output.length; i += 1) {
                    output[i] = 0;
                }
                for (i = 0; i < input.length * 8; i += 8) {
                    output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
                }
                return output;
            }

            /*
            * Calculate the MD5 of a raw string
            */
            function rstr_md5(s) {
                return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
            }

            /*
            * Calculate the HMAC-MD5, of a key and some data (raw strings)
            */
            function rstr_hmac_md5(key, data) {
                var i,
                    bkey = rstr2binl(key),
                    ipad = [],
                    opad = [],
                    hash;
                ipad[15] = opad[15] = undefined;
                if (bkey.length > 16) {
                    bkey = binl_md5(bkey, key.length * 8);
                }
                for (i = 0; i < 16; i += 1) {
                    ipad[i] = bkey[i] ^ 0x36363636;
                    opad[i] = bkey[i] ^ 0x5C5C5C5C;
                }
                hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
                return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
            }

            /*
            * Convert a raw string to a hex string
            */
            function rstr2hex(input) {
                var hex_tab = '0123456789abcdef',
                    output = '',
                    x,
                    i;
                for (i = 0; i < input.length; i += 1) {
                    x = input.charCodeAt(i);
                    output += hex_tab.charAt((x >>> 4) & 0x0F) +
                        hex_tab.charAt(x & 0x0F);
                }
                return output;
            }

            /*
            * Encode a string as utf-8
            */
            function str2rstr_utf8(input) {
                return unescape(encodeURIComponent(input));
            }

            /*
            * Take string arguments and return either raw or hex encoded strings
            */
            function raw_md5(s) {
                return rstr_md5(str2rstr_utf8(s));
            }

            function hex_md5(s) {
                return rstr2hex(raw_md5(s));
            }

            function raw_hmac_md5(k, d) {
                return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d));
            }

            function hex_hmac_md5(k, d) {
                return rstr2hex(raw_hmac_md5(k, d));
            }

            function md5(string, key, raw) {
                if (!key) {
                    if (!raw) {
                        return hex_md5(string);
                    }
                    return raw_md5(string);
                }
                if (!raw) {
                    return hex_hmac_md5(key, string);
                }
                return raw_hmac_md5(key, string);
            }

            $.md5 = md5;
        }($));
    },
    timeFormat: function(time) {
        var arr = time.split(':');
        return arr[0] * 60 * 60 + arr[1] * 60 + arr[2] * 1;
    },
    floadObj: (function(){
        /*
        * 判断obj是否为一个整数
        */
        function isInteger(obj) {
            return Math.floor(obj) === obj;
        }

        /*
        * 将一个浮点数转成整数，返回整数和倍数。如 3.14 >> 314，倍数是 100
        * @param floatNum {number} 小数
        * @return {object}
        *   {times:100, num: 314}
        */
        function toInteger(floatNum) {
            var ret = {times: 1, num: 0};
            var isNegative = floatNum < 0;//是否为负数
            if (isInteger(floatNum)) {
                ret.num = floatNum;
                return ret;
            }
            var strfi  = floatNum + '';
            var dotPos = strfi.indexOf('.');
            var len    = strfi.substr(dotPos+1).length;//获取小数位数
            var times  = Math.pow(10, len);
            var intNum = parseInt(Math.abs(floatNum) * times + 0.5, 10);
            ret.times  = times;
            if (isNegative) {
                intNum = -intNum;
            }
            ret.num = intNum;
            return ret;
        }

        /*
        * 核心方法，实现加减乘除运算，确保不丢失精度
        * 思路：把小数放大为整数（乘），进行算术运算，再缩小为小数（除）
        *
        * @param a {number} 运算数1
        * @param b {number} 运算数2
        * @param digits {number} 精度，保留的小数点数，比如 2, 即保留为两位小数
        * @param op {string} 运算类型，有加减乘除（add/subtract/multiply/divide）
        *
        */
        function operation(a, b, digits, op) {
            var o1 = toInteger(a)
            var o2 = toInteger(b)
            var n1 = o1.num
            var n2 = o2.num
            var t1 = o1.times
            var t2 = o2.times
            var max = t1 > t2 ? t1 : t2
            var result = null
            switch (op) {
                case 'add':
                    if (t1 === t2) { // 两个小数位数相同
                        result = n1 + n2
                    } else if (t1 > t2) { // o1 小数位 大于 o2
                        result = n1 + n2 * (t1 / t2)
                    } else { // o1 小数位 小于 o2
                        result = n1 * (t2 / t1) + n2
                    }
                    return result / max
                case 'subtract':
                    if (t1 === t2) {
                        result = n1 - n2
                    } else if (t1 > t2) {
                        result = n1 - n2 * (t1 / t2)
                    } else {
                        result = n1 * (t2 / t1) - n2
                    }
                    return result / max
                case 'multiply':
                    result = (n1 * n2) / (t1 * t2)
                    return result
                case 'divide':
                    result = (n1 / n2) * (t2 / t1)
                    return result
            }
        }
        
        // 加减乘除的四个接口
        function add(a, b, digits) {
            return operation(a, b, digits, 'add')
        }
        function subtract(a, b, digits) {
            return operation(a, b, digits, 'subtract')
        }
        function multiply(a, b, digits) {
            return operation(a, b, digits, 'multiply')
        }
        function divide(a, b, digits) {
            return operation(a, b, digits, 'divide')
        }

        return {
            add: add,
            subtract: subtract,
            multiply: multiply,
            divide: divide
        }
    })(),
    signUtil: {
        //加密/解密次数
        num: 0,
        //加密
        Encrypt: function (Text) {
            this.num = this.num + 1;
            output = new String;
            alterText = new Array();
            varCost = new Array();
            TextSize = Text.length;
            for (i = 0; i < TextSize; i++) {
                idea = Math.round(Math.random() * 111) + 77;
                alterText[i] = Text.charCodeAt(i) + idea;
                varCost[i] = idea;
            }
            for (i = 0; i < TextSize; i++) {
                output += String.fromCharCode(alterText[i], varCost[i]);
            }
            return output;
        },
        //解密
        UnEncrypt: function (Text) {
            if (this.num > 0) {
                this.num = this.num - 1;
                output = new String;
                alterText1 = new Array();
                varCost1 = new Array();
                TextSize = Text.length;
                for (i = 0; i < TextSize; i++) {
                    alterText[i] = Text.charCodeAt(i);
                    varCost[i] = Text.charCodeAt(i + 1);
                }
                for (i = 0; i < TextSize; i = i + 2) {
                    output += String.fromCharCode(alterText[i] - varCost[i]);
                }
                return output;
            }
        }
    },
    //本地缓存的适配打点-操作封装
    getOrSetLocalStorage: function(key, value, keys){//key,value:写入、keys删除
        var returnObj = {"nows": [], "logs": []};
        var localData = null;
        //get
            try{
                var storage = window.localStorage;
                if(storage){
                    if(storage.getItem("nhd")){
                        localData = storage.getItem("nhd");
                    }
                }
            }catch(e){
                localData = null;
            }
        if(localData){
            localData = JSON.parse(localData);
            if(toString.call(localData) != "[object Object]") localData = {};
        }else{
            localData = {};
        }
        //追加
        if(key && value){
            localData[key] = value;
        }
        //delete
        if(keys){
            if(toString.call(keys) == "[object Array]"){
            for(var k=0; k<keys.length; k++){
                delete localData[keys[k]];
            }
            }
        }
        //set
        try{
            var storage = window.localStorage;
            if(storage){
            storage.setItem("nhd", JSON.stringify(localData));
            }
        }catch(e){
        }

        var returnSum = 0;
        for(var i in localData){
            if(localData[i]){
            if(returnSum < 50){
                returnObj.nows.push(i);
                returnObj.logs.push(localData[i]);
                returnSum = returnObj.nows.length;//每次上传不超过50个点
            }else{
                continue;
            }
            }
        }
        return returnObj;
    },
    setLocalStorageItem: function(key, value){
        try{
            var storage = window.localStorage;
            if(storage){
                storage.setItem(key, value);
            }
        }catch(e){
        }
    },
    getLocalStorageItem: function(key){
        try{
            var storage = window.localStorage;
            if(storage){
                var value = null;
                if(storage.getItem(key)){
                    value = storage.getItem(key);
                }
                return value;
            }
        }catch(e){
            return null;
        }
    },
    removeLocalStorageItem: function(key){
        try{
            var storage = window.localStorage;
            if(storage){
                storage.removeItem(key);
            }
        }catch(e){
        }
    },
    getAllLocalStorage: function(){//获取所有本地存储，并拼装成JSON对象返回
        try{
            var storage = window.localStorage;
            if(storage){
                var all = {};
                for(var i=0;i<storage.length;i++){
                    var key = storage.key(i);
                    all[key] = storage.getItem(key);
                }
                return all;
            }
        }catch(e){
            return null;
        }
    },
    clearAllLocalStorage: function(){
        try{
            var storage = window.localStorage;
            if(storage){
                storage.clear();
            }
        }catch(e){
            return null;
        }
    },
    getCookie: function(key, isJSON){
        var converter = function(){};
        if (typeof document === 'undefined') {
            return;
        }
        var jar = {};
        // To prevent the for loop in the first place assign an empty array
        // in case there are no cookies at all.
        var cookies = document.cookie ? document.cookie.split('; ') : [];
        var i = 0;

        for (; i < cookies.length; i++) {
            var parts = cookies[i].split('=');
            var cookie = parts.slice(1).join('=');

            if (!isJSON && cookie.charAt(0) === '"') {
                cookie = cookie.slice(1, -1);
            }

            try {
                var name = parts[0].replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);
                cookie = (converter.read || converter)(cookie, name) || cookie.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);
                if (isJSON) {
                    try {
                        cookie = JSON.parse(cookie);
                    } catch (e) {}
                }

                jar[name] = cookie;

                if (key === name) {
                    break;
                }
            } catch (e) {}
        }

        return key ? jar[key] : jar;
    },
    _ajax: function(params) { // 全局ajax封装
        if (params.async === undefined) {
            params.async = true;
        }
        if (params.success && typeof params.success == 'function') {
            var _success = params.success;
            params.success = (function(fn) {
                return function(data) {
                    fn({
                        'data': data
                    });
                };
            })(_success);
        }
        $.ajax(params);
    },
    client: function(){
        var USER_AGENT = window.navigator && window.navigator.userAgent || '';
        var webkitVersionMap = (/AppleWebKit\/([\d.]+)/i).exec(USER_AGENT);
        var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;

        /*
        * Device is an iPhone
        *
        * @type {Boolean}
        * @constant
        * @private
        */
        var IS_IPAD = (/iPad/i).test(USER_AGENT);

        // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
        // to identify iPhones, we need to exclude iPads.
        // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
        var IS_IPHONE = (/iPhone/i).test(USER_AGENT) && !IS_IPAD;
        var IS_IPOD = (/iPod/i).test(USER_AGENT);
        var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;

        var IOS_VERSION = (function() {
            var match = USER_AGENT.match(/OS (\d+)_/i);

            if (match && match[1]) {
            return match[1];
            }
            return null;
        }());

        var IS_ANDROID = (/Android/i).test(USER_AGENT);
        var ANDROID_VERSION = (function() {
            // This matches Android Major.Minor.Patch versions
            // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
            var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
        
            if (!match) {
                return null;
            }
        
            var major = match[1] && parseFloat(match[1]);
            var minor = match[2] && parseFloat(match[2]);
        
            if (major && minor) {
                return parseFloat(match[1] + '.' + match[2]);
            } else if (major) {
                return major;
            }
            return null;
        }());

        // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
        var IS_OLD_ANDROID = IS_ANDROID && (/webkit/i).test(USER_AGENT) && ANDROID_VERSION < 2.3;
        var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;

        var IS_FIREFOX = (/Firefox/i).test(USER_AGENT);
        var IS_EDGE = (/Edge/i).test(USER_AGENT);
        var IS_CHROME = !IS_EDGE && (/Chrome/i).test(USER_AGENT);
        var CHROME_VERSION = (function() {
            var match = USER_AGENT.match(/Chrome\/(\d+)/);
        
            if (match && match[1]) {
                return parseFloat(match[1]);
            }
            return null;
        }());
        var IS_IE8 = (/MSIE\s8\.0/).test(USER_AGENT);
        var IE_VERSION = (function() {
            var result = (/MSIE\s(\d+)\.\d/).exec(USER_AGENT);
            var version = result && parseFloat(result[1]);
        
            if (!version && (/Trident\/7.0/i).test(USER_AGENT) && (/rv:11.0/).test(USER_AGENT)) {
                // IE 11 has a different user agent string than other IE versions
                version = 11.0;
            }
        
            return version;
        }());

        var IS_SAFARI = (/Safari/i).test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
        var IS_ANY_SAFARI = IS_SAFARI || IS_IOS;

        var TOUCH_ENABLED = (
        'ontouchstart' in window ||
        window.DocumentTouch &&
        window.document instanceof window.DocumentTouch);

        var BACKGROUND_SIZE_SUPPORTED = ('backgroundSize' in window.document.createElement('video').style);
        
        var ISWECHAT = USER_AGENT.toLowerCase().match(/micromessenger/i) == "micromessenger";
        
        var ISMOBILE = function(i){
            var sUserAgent= i.toLowerCase(),
            bIsIpad= sUserAgent.match(/ipad/i) == "ipad",
            bIsIphoneOs= sUserAgent.match(/iphone os/i) == "iphone os",
            bIsMidp= sUserAgent.match(/midp/i) == "midp",
            bIsUc7= sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4",
            bIsUc= sUserAgent.match(/ucweb/i) == "ucweb",
            bIsAndroid= sUserAgent.match(/android/i) == "android",
            bIsCE= sUserAgent.match(/windows ce/i) == "windows ce",
            bIsWM= sUserAgent.match(/windows mobile/i) == "windows mobile",
            bIsWECHAT = sUserAgent.match(/micromessenger/i) == "micromessenger",
            bIsWebview = sUserAgent.match(/webview/i) == "webview";
            return (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM || bIsWECHAT || bIsWebview);
        }(USER_AGENT);
        
        return {
            IS_IPAD: IS_IPAD,
            IS_IPHONE: IS_IPHONE,
            IS_IPOD: IS_IPOD,
            IS_IOS: IS_IOS,
            IOS_VERSION: IOS_VERSION,
            IS_ANDROID: IS_ANDROID,
            ANDROID_VERSION: ANDROID_VERSION,
            IS_OLD_ANDROID: IS_OLD_ANDROID,
            IS_NATIVE_ANDROID: IS_NATIVE_ANDROID,
            IS_FIREFOX: IS_FIREFOX,
            IS_EDGE: IS_EDGE,
            IS_CHROME: IS_CHROME,
            CHROME_VERSION: CHROME_VERSION,
            IS_IE8: IS_IE8,
            IE_VERSION: IE_VERSION,
            IS_SAFARI: IS_SAFARI,
            IS_ANY_SAFARI: IS_ANY_SAFARI,
            TOUCH_ENABLED: TOUCH_ENABLED,
            BACKGROUND_SIZE_SUPPORTED: BACKGROUND_SIZE_SUPPORTED,
            ISWECHAT: ISWECHAT,
            ISMOBILE: ISMOBILE || TOUCH_ENABLED
        };
    }
}
export default util;